<template>
  <el-form :model="formData as FormData" :rules="formRules" label-width="80px" ref="form" v-loading="loading" class="px-6">
    <el-form-item label="任务名称" prop="task_name" required>
      <el-input v-model="(formData as FormData).task_name" name="task_name" placeholder="请输入数据核对任务名称" clearable class="custom-input" />
    </el-form-item>

    <!-- 文件上传区域 -->
    <div class="file-upload-section">
      <div class="upload-grid">
        <!-- 源文件上传 -->
        <el-form-item label="核对表" prop="target_file_original_name" class="upload-item" required>
          <div class="file-upload-container">
            <el-upload ref="targetUploadRef" class="button-upload" :http-request="targetFileUpload" :before-upload="beforeTargetUpload" :show-file-list="false">
              <el-tooltip content="支持 xlsx、xls、csv 格式，文件大小不超过 10MB" placement="top">
                <el-button type="primary" :icon="UploadFilled" :loading="targetUploadLoading">
                  {{ formData.target_file_original_name ? '重新上传文件' : '选择核对文件' }}
                </el-button>
              </el-tooltip>
            </el-upload>
            <!-- 已上传文件信息 -->
            <div v-if="formData.target_file_original_name" class="selected-file-card">
              <div class="file-card-header">
                <div class="file-card-info">
                  <div class="file-icon-container">
                    <img v-if="getFileIcon(formData.source_file_original_name)" src="@/public/assets/xls.png" alt="file-icon" class="file-icon"></img>
                    <img v-else src="@/public/assets/file.png" alt="file-icon" class="file-icon"></img>
                  </div>
                  <div class="file-details">
                    <div class="file-main-info">
                      <span class="file-name">{{ formData.target_file_original_name }}</span>
                    </div>
                  </div>
                </div>
                <el-button type="danger" link size="small" class="remove-btn" @click="removeFile('target_file')">
                  <el-icon><Close /></el-icon>
                </el-button>
              </div>
            </div>
          </div>
        </el-form-item>

        <!-- 目标文件上传 -->
        <el-form-item label="总表" prop="source_file_original_name" class="upload-item" required>
          <div class="file-upload-container">
            <!-- 上传按钮区域 -->
            <div class="justify-between upload-button-group">
              <el-upload ref="sourceUploadRef" class="button-upload" :http-request="sourceFileUpload" :before-upload="beforeSourceUpload" :show-file-list="false">
                <el-tooltip content="支持 xlsx、xls、csv 格式，文件大小不超过 10MB" placement="top">
                  <el-button type="primary" :icon="UploadFilled" :loading="sourceUploadLoading">
                    {{ formData.source_file_original_name ? '重新上传文件' : '选择总表文件' }}
                  </el-button>
                </el-tooltip>
              </el-upload>

              <!-- 历史记录按钮 -->
              <el-dropdown v-if="targetFileHistory.length > 0" @command="selectHistoryFile" trigger="click" class="history-button">
                <el-button type="info" plain :icon="Clock" size="default"> 历史记录 </el-button>
                <template #dropdown>
                  <el-dropdown-menu class="history-menu">
                    <el-dropdown-item v-for="(file, index) in targetFileHistory" :key="index" :command="file" class="history-item">
                      <div class="history-file-info">
                        <img v-if="getFileIcon(file.name)" src="@/public/assets/xls.png" alt="file-icon" class="history-file-icon"></img>
                        <img v-else src="@/public/assets/file.png" alt="file-icon" class="history-file-icon"></img>
                        <div class="history-file-details">
                          <div class="history-file-name">{{ file.name }}</div>
                          <div class="history-file-meta">
                            {{ file.last_used_time }}
                          </div>
                        </div>
                        <el-tag v-if="index === 0" size="small" type="success" effect="light">最近</el-tag>
                      </div>
                    </el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>

            <!-- 已选择文件信息 -->
            <div v-if="formData.source_file_original_name" class="selected-file-card">
              <div class="file-card-header">
                <div class="file-card-info">
                  <div class="file-icon-container">
                    <img v-if="getFileIcon(formData.source_file_original_name)" src="@/public/assets/xls.png" alt="file-icon" class="file-icon"></img>
                    <img v-else src="@/public/assets/file.png" alt="file-icon" class="file-icon"></img>
                  </div>
                  <div class="file-details">
                    <div class="file-main-info">
                      <span class="file-name">{{ formData.source_file_original_name }}</span>
                    </div>
                    <div v-if="isSourceHistory" class="file-source-info">
                      <el-icon class="source-icon"><Clock /></el-icon>
                      <span class="source-text">来自历史记录</span>
                    </div>
                  </div>
                </div>
                <el-button type="danger" link size="small" class="remove-btn" @click="removeFile('source_file')">
                  <el-icon><Close /></el-icon>
                </el-button>
              </div>
            </div>
          </div>
        </el-form-item>
      </div>
    </div>

    <div class="form-actions">
      <el-button type="primary" @click="submitForm" size="large" class="submit-btn" :disabled="!canSubmit">
        <el-icon><Check /></el-icon>
        确定
      </el-button>
    </div>
  </el-form>
</template>

<script lang="ts" setup>
import { computed, inject, onMounted, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { UploadFilled, Check, Close, Clock, Files } from '@element-plus/icons-vue'
import http from '@/support/http'
import Message from '@/support/message'
import { Code } from '@/enum/app'
import type { FormInstance, UploadInstance, UploadFile, UploadFiles, UploadRawFile } from 'element-plus'
import { fi } from 'element-plus/es/locale'

/**
 * 文件上传相关常量
 */
const FILE_TYPES = [
  'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
  'application/vnd.ms-excel', // .xls
  'text/csv' // .csv
] as const

const FILE_ACCEPT = '.xlsx,.xls,.csv'
const MAX_FILE_SIZE = 10 * 1024 * 1024 // 10MB
const SUCCESS_CODE = 10000

/**
 * 历史文件接口
 */
interface HistoryFile {
  id: number
  name: string
  path: string
  size?: number
  last_used_time?: string
}

/**
 * 表单数据接口
 */
interface FormData {
  task_name?: string
  source_file?: string
  source_file_original_name?: string
  source_file_id?: number
  target_file?: string
  target_file_original_name?: string
}

const props = defineProps<{
  primary?: string | number
  api?: string
}>()

// 表单验证规则
const formRules = ref({
  task_name: [
    { required: true, message: '请输入任务名称', trigger: 'blur' },
    { min: 2, max: 50, message: '任务名称长度应在2到50个字符之间', trigger: 'blur' }
  ],
  source_file_original_name: [{ required: true, message: '请上传总表文件', trigger: 'change' }],
  target_file_original_name: [{ required: true, message: '请上传核对表文件', trigger: 'change' }]
})

// 文件上传相关
const sourceUploadRef = ref<UploadInstance>()
const targetUploadRef = ref<UploadInstance>()
const sourceUploadLoading = ref(false)
const targetUploadLoading = ref(false)
// 历史记录相关
const targetFileHistory = ref<HistoryFile[]>([])

// 表单相关
const formData = ref<FormData>({} as FormData)
const loading = ref(false)
const form = ref<FormInstance>()
const isClose = ref(false)

/**
 * 提交表单
 * @param formEl 表单实例
 */
const submitForm = () => {
  if (!form.value) return
  form.value.validate(valid => {
    if (valid) {
      loading.value = true
      const api = props.api || ''
      const promise = props.primary ? http.setHeader('Content-Type', 'application/json').put(`${api}/${props.primary}`, formData.value) : http.post(api, formData.value)

      promise
        .then(r => {
          if (r.data.code === Code.SUCCESS) {
            isClose.value = true
            Message.success(r.data.message)
          } else {
            Message.error(r.data.message)
          }
        })
        .catch(error => {
          Message.error(error?.response?.data?.message || '操作失败，请重试')
        })
        .finally(() => {
          loading.value = false
        })
    }
  })
}

/**
 * 监听关闭状态，执行关闭回调
 */
const closeDialog = inject<() => void>('closeDialog')
watch(isClose, value => {
  if (value && closeDialog) {
    closeDialog()
  }
}) 
const getFileIcon = (fileName?: string) => {
  if (!fileName) return false
  return fileName.split('.').pop() === 'xls' || fileName.split('.').pop() === 'xlsx'
}
const targetFileUpload = async (file: UploadRawFile) => {
  targetUploadLoading.value = true
  await fileUpload(file, 'target_file')
}
const beforeTargetUpload = (file: UploadRawFile) => {
  return validateFile(file)
}
const sourceFileUpload = async (file: UploadRawFile) => {
  sourceUploadLoading.value = true
  await fileUpload(file, 'source_file')
}
const beforeSourceUpload = (file: UploadRawFile) => {
  return validateFile(file)
}
const fileUpload = async (request: any, field: string) => {
  try {
    http.setHeader('Content-Type', 'multipart/form-data')
    const res = await http.post('/upload/file', { file: request.file })

    if (field === 'target_file') {
      formData.value.target_file = res.data.data.path || ''
      formData.value.target_file_original_name = res.data.data.originalName || ''
    } else if (field === 'source_file') {
      formData.value.source_file = res.data.data.path || ''
      formData.value.source_file_original_name = res.data.data.originalName || ''
      formData.value.source_file_id = 0
    }
  } catch (error) {
    targetUploadLoading.value = false
    Message.error('上传失败，请重试')
  } finally {
    targetUploadLoading.value = false
    sourceUploadLoading.value = false
  }
}

const removeFile = (field: string) => {
  if (field === 'target_file') {
    formData.value.target_file = ''
    formData.value.target_file_original_name = ''
  } else if (field === 'source_file') {
    formData.value.source_file = ''
    formData.value.source_file_original_name = ''
    formData.value.source_file_id = 0
  }
}
/**
 * 文件上传前验证
 * @param file 上传的文件
 * @returns 是否允许上传
 */
const validateFile = (file: UploadRawFile): boolean => {
  const isValidType = FILE_TYPES.includes(file.type as (typeof FILE_TYPES)[number])
  if (!isValidType) {
    ElMessage.error('只能上传 Excel 或 CSV 文件!')
    return false
  }

  if (file.size > MAX_FILE_SIZE) {
    ElMessage.error('文件大小不能超过 10MB!')
    return false
  }

  return true
}

const isSourceHistory = ref(false)
watch(
  () => formData.value.source_file,
  val => {
    isSourceHistory.value = targetFileHistory.value.some(file => file.path === val)
  },
  { immediate: true, deep: true }
)
/**
 * 选择历史文件
 * @param file 历史文件对象
 * @param showToast 是否显示提示消息
 */
const selectHistoryFile = (file: HistoryFile, showToast = true) => {
  formData.value.source_file_original_name = file.name
  formData.value.source_file_id = file.id
  formData.value.source_file = file.path
  // 触发表单验证
  form.value?.validateField('source_file_original_name')

  // 只有在手动选择时才显示提示消息
  if (showToast) {
    ElMessage.success(`已选择历史总表文件：${file.name}`)
  }
}

/**
 * 加载总表文件历史记录
 */
const loadTargetFileHistory = async () => {
  try {
    const response = await http.get('dc/task/history')
    const result = response.data

    if (result.code === SUCCESS_CODE && result.data) {
      targetFileHistory.value = result.data

      // 自动选择最近的总表文件
      if (targetFileHistory.value.length > 0 && !formData.value.source_file_original_name) {
        const latestFile = targetFileHistory.value[0]
        selectHistoryFile(latestFile, false) // 不显示toast提示
      }
    } else {
      targetFileHistory.value = []
    }
  } catch (error) {
    ElMessage.warning('加载历史记录失败，请稍后重试')
    targetFileHistory.value = []
  }
}

/**
 * 计算是否允许提交表单
 */
const canSubmit = computed(() => {
  return !!(formData.value.source_file_original_name && formData.value.target_file_original_name)
})
/**
 * 获取详情
 */
const getDetail = async () => {
  if (props.primary && props.api) {
    try {
      loading.value = true
      const res = await http.get(props.api + '/' + props.primary)
      if (res.data.code === SUCCESS_CODE) {
        formData.value = res.data.data
      }
    } catch (error) {
      Message.error('获取详情失败，请稍后重试')
    } finally {
      loading.value = false
    }
  }
}
/**
 * 组件挂载时的初始化操作
 */
onMounted(async () => {
  // 加载历史记录并自动选择最近的总表文件
  formData.value = {}
  loadTargetFileHistory()
  getDetail()
})
</script>

<style scoped>
/* 输入框样式 */
.custom-input :deep(.el-input__wrapper) {
  border-radius: 8px;
  box-shadow: 0 0 0 1px #d9d9d9 inset;
  transition: all 0.3s;
}

.custom-input :deep(.el-input__wrapper:hover) {
  box-shadow: 0 0 0 1px #40a9ff inset;
}

.custom-input :deep(.el-input__wrapper.is-focus) {
  box-shadow: 0 0 0 1px #1890ff inset;
}

/* 文件上传区域 */
.file-upload-section {
  margin: 20px 0;
  max-width: 100%;
  overflow: hidden;
}

.upload-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  max-width: 100%;
}

.upload-item {
  margin-bottom: 0;
}

.upload-item :deep(.el-form-item__label) {
  font-weight: 600;
  color: #333;
  margin-bottom: 12px;
}

/* 统一所有表单标签样式 */
:deep(.el-form-item__label) {
  font-weight: 600 !important;
  color: #333 !important;
  font-size: 14px !important;
  text-align: right !important;
}

.file-upload-container {
  width: 100%;
  min-width: 0; /* 防止flex子项溢出 */
}

/* 上传按钮组样式 */
.upload-button-group {
  display: flex;
  gap: 12px;
  margin-bottom: 12px;
}

.main-upload {
  flex: 1;
}

.history-button {
  flex-shrink: 0;
}

/* 历史记录菜单样式 */
.history-menu {
  min-width: 280px;
  padding: 4px 0;
}

.history-item {
  padding: 8px 16px !important;
}

.history-file-info {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
}

.history-file-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.history-file-details {
  flex: 1;
  min-width: 0;
}

.history-file-name {
  font-size: 13px;
  font-weight: 500;
  color: #303133;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 2px;
}

.history-file-meta {
  font-size: 11px;
  color: #909399;
}

/* 已选择文件卡片样式 */
.selected-file-card {
  margin-top: 8px;
  border: 1px solid #e8e8e8;
  border-radius: 8px;
  background: #ffffff;
  transition: all 0.2s ease;
}

.selected-file-card:hover {
  border-color: #409eff;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
}

.file-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px;
  min-height: 72px;
}

.file-card-info {
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  flex: 1;
  min-width: 0;
}

.file-icon-container {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;  
}

.file-card-info .file-icon {
  font-size: 20px;
  color: #ffffff;
}

.file-details {
  flex: 1;
  min-width: 0;
}

.file-main-info {
  margin-bottom: 2px;
}

.file-card-info .file-name {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-decoration: underline;
  text-decoration-color: transparent;
  transition: all 0.2s ease;
}

.file-source-info {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 2px;
}

.source-icon {
  font-size: 12px;
  color: #67c23a;
}

.source-text {
  font-size: 12px;
  color: #67c23a;
  font-weight: 500;
}

.remove-btn {
  flex-shrink: 0;
  margin-left: 12px;
  padding: 8px;
  border-radius: 50%;
  transition: all 0.2s ease;
}

.remove-btn:hover {
  background-color: #fef0f0;
}

/* 表单操作区域 */
.form-actions {
  display: flex;
  justify-content: center;
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid #f0f0f0;
}

.submit-btn {
  padding: 12px 32px;
  font-size: 16px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;
}

.submit-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.submit-btn .el-icon {
  font-size: 16px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .upload-grid {
    gap: 16px;
  }

  .upload-button-group {
    flex-direction: column;
    gap: 8px;
  }

  .history-menu {
    min-width: 260px;
  }

  .selected-file-card {
    margin-top: 12px;
  }

  .file-card-header {
    padding: 12px;
  }

  .file-icon-container {
    width: 36px;
    height: 36px;
  }

  .file-card-info .file-icon {
    font-size: 18px;
  }

  .file-card-info .file-name {
    font-size: 13px;
  }

  .source-text {
    font-size: 11px;
  }

  .submit-btn {
    width: 100%;
    justify-content: center;
  }
}

@media (max-width: 480px) {
  .file-upload-section {
    margin: 16px 0;
  }

  .upload-grid {
    gap: 12px;
  }

  .upload-button-group {
    gap: 6px;
  }

  .history-menu {
    min-width: 240px;
  }

  .history-item {
    padding: 6px 12px !important;
  }

  .history-file-name {
    font-size: 12px;
  }

  .history-file-meta {
    font-size: 10px;
  }

  .selected-file-card {
    margin-top: 10px;
  }

  .file-card-header {
    padding: 10px;
  }

  .file-icon-container {
    width: 32px;
    height: 32px;
  }

  .file-card-info .file-icon {
    font-size: 16px;
  }

  .file-card-info .file-name {
    font-size: 12px;
  }

  .source-text {
    font-size: 10px;
  }
}
</style>
